【详解】树莓派开源驱动库BCM2835之SPI

您所在的位置:网站首页 bcm2835 gpio 【详解】树莓派开源驱动库BCM2835之SPI

【详解】树莓派开源驱动库BCM2835之SPI

2022-08-16 17:41| 来源: 网络整理| 查看: 265

{

if (!bcm2835_init)//所有外围io引脚初始化,之前已经分析过了

{

printf("bcm2835_init failed. Are you running as root??n");

return 1;

}

/*spi相关的功能引脚初始化,主要的是将spi对应的io设置成spi功能,将CS寄存器清0,清spi TX和RX的接收发送缓存。

*/

if (!bcm2835_spi_begin){

printf("bcm2835_spi_begin failed. Are you running as root??n");

return 1;

}

bcm2835_spi_begin;

bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);

//The default

/*将SPI的数据通信模式设置为模式BCM2835_SPI_MODE0,即CPOL = 0, CPHA = 0

CPOL = 0通信空闲状态时时钟线为高电平,CPHA = 0第二个时钟边沿采样数据。

*/

bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);

//The default

//时钟分频

bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536);

//拉低片选引脚

bcm2835_spi_chipSelect(BCM2835_SPI_CS0);

bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);

//the default

char buf[] = { 0x01, 0x02, 0x11, 0x33 };//Data to send

bcm2835_spi_transfern(buf, sizeof(buf));//数据发送和接收

//buf will now be filled with the data that was read from the slave

printf("Read from SPI: %02X %02X %02X %02X n", buf[0], buf[1], buf[2], buf[3]);

bcm2835_spi_end;

bcm2835_close;

return 0;

}

bcm2835_spi_transfern是通过调用bcm2835_spi_transfernb来完成数据的发送的。

void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)

{

volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;

volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;

uint32_t TXCnt=0;

uint32_t RXCnt=0;

/* Clear TX and RX fifos */

bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);

/* Set TA = 1,设置TA将SPI恢复到未通信状态 */

bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);

/* Use the FIFO's to reduce the interbyte times */

while((TXCnt < len)||(RXCnt < len))//发送和接收循环

{

/* TX fifo not full, so add some more bytes */

while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))&&(TXCnt < len ))

{

bcm2835_peri_write_nb(fifo, tbuf[TXCnt]);

TXCnt++;

}

/* Rx fifo not empty, so get the next received bytes */

while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD))&&( RXCnt < len ))

{

rbuf[RXCnt] = bcm2835_peri_read_nb(fifo);

RXCnt++;

}

}

/* Wait for DONE to be set */

//等待通信结束

while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE));

/* Set TA = 0, and also set the barrier */

bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);//设置TA位结束通信

}

←左右滑动,查看全部代码→

实 例 效 果

下面借助图片来看一下树莓派spin.c回环实验的效果。

上图是用逻辑分析仪抓到的数据,channel 1和channel 2分别是MOSI和MISO,channel 3是时钟信号,时钟模式为CPOL = 0, CPHA = 0。CS片选为channel 4,通信时将其拉低使能SPI。

下图是树莓派3的外围IO图,左红色方框是spi的主要三个引脚,右边CE可不接,做loop是将MOSI和MISO互连,GDN和逻辑分析仪互连(最好相连,否则参考电平不同可能会出现解码错误)。

*本文作者为CSDN博主「KosingZhu」

原文地址为

https://blog.csdn.net/housezhu/article/details/77926641返回搜狐,查看更多



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3